package org.pas.fb2.tag;

public abstract class Tag {

    private final Tag parent;

    public Tag(Tag parent) {
        this.parent = parent;
    }

    public Tag getParent() {
        return parent;
    }

    public boolean hasParent() {
        return parent != null;
    }

    public abstract String getName();

    public Tag onChild(String name) {
        return new DummyTag(this, name);
    }

    public Tag onClose(String name) {
        if (getName().equals(name)) {
            doClose();
            return parent;
        } else {
            return this;
        }
    }

    public void onChars(char ch[], int start, int length) {
        // do nothing by default
    }

    protected void doClose() {
        // do nothing by default
    }

    protected void out(CharSequence sequence) {
        getParent().out(sequence);
    }

    protected void emptyLine(boolean forced) {
        getParent().emptyLine(forced);
    }

    protected static CharSequence removeSpaces(CharSequence chars) {
        StringBuilder buf = new StringBuilder(chars.length());
        boolean isPrevSpace = true;
        for (int i = 0; i < chars.length(); i++) {
            char ch = chars.charAt(i);
            boolean isCurSpace = ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
            if (!(isPrevSpace && isCurSpace)) {
                if (ch == '\n' || ch == '\r' || ch == '\t') {
                    buf.append(' ');
                } else {
                    buf.append(ch);
                }
            }
            isPrevSpace = isCurSpace;
        }
        while (buf.length() > 0 && buf.charAt(buf.length() - 1) == ' ') {
            buf.setLength(buf.length() - 1);
        }
        return buf;
    }

    protected CharSequence getPath() {
        StringBuilder buf = new StringBuilder();
        Tag tag = this;
        while (tag.hasParent()) {
            buf.insert(0, tag.getName()).insert(0, "/");
            tag = tag.getParent();
        }
        return buf;
    }
}
